﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.BusinessData.SystemSpecific;
using Microsoft.BusinessData.MetadataModel;
using Microsoft.BusinessData.Runtime;
using System.Diagnostics;
using System.IO.Packaging;

namespace TFSCustomConnector
{
    public partial class TFSNETService : IContextProperty
    {
        private static IMethodInstance methodInstance;
        private static ILobSystemInstance lobSystemInstance;
        private static IExecutionContext executionContext;

        #region IContextProperty implementation

        public IMethodInstance MethodInstance
        {
            get { return methodInstance; }
            set { methodInstance = value; }
        }

        public ILobSystemInstance LobSystemInstance
        {
            get { return lobSystemInstance; }
            set { lobSystemInstance = value; }
        }

        public IExecutionContext ExecutionContext
        {
            get { return executionContext; }
            set { executionContext = value; }
        }

        #endregion

        private static DynamicType GenerateDynamicItemStructure(IMethodInstance methodInstance)
        {
            string IdentifierName = null;
            DynamicType dt = new DynamicType();

            ITypeDescriptor typeDescriptor = (methodInstance.MethodInstanceType == MethodInstanceType.Finder || 
                                                methodInstance.MethodInstanceType == MethodInstanceType.AssociationNavigator) ?
                methodInstance.GetMethod().GetParameters()[1].GetRootTypeDescriptor().GetChildTypeDescriptors()[0] :
                methodInstance.GetMethod().GetParameters()[1].GetRootTypeDescriptor();

            foreach (ITypeDescriptor childDescpritor in typeDescriptor.GetChildTypeDescriptors())
            {
                dt.Add(childDescpritor.Name, null);
                if (childDescpritor.IsIdentifierSet) IdentifierName = childDescpritor.GetIdentifier().Name;
            }

            if (IdentifierName == null) throw (new ArgumentNullException("Identifier is absent"));

            return dt;
        }

        public static DynamicType[] FindAssociations(int ID)
        {
            string TfsConnURL = (string)lobSystemInstance.GetProperties()["TFSConnectionURL"];
            string TfsWIType = (string)methodInstance.GetMethod().GetDataClass().GetProperties()["TFSWorkItemType"]; //methodInstance.GetMethod().GetDataClass().Name
            string lobSystemName = lobSystemInstance.Name;

            //Log("ExecuteStatic", methodInstance.MethodInstanceType.ToString(), lobSystemName, TfsWIType);
            DynamicType template = GenerateDynamicItemStructure(methodInstance);
            DynamicType[] dynItemList = AttachHelper.FindAssociations(template, TfsConnURL, ID, lobSystemName, TfsWIType);
            return dynItemList;
        }
        
        public static DynamicType ReadItem(int ID)
        {
            DynamicType template;
            string TfsConnURL = (string)lobSystemInstance.GetProperties()["TFSConnectionURL"];
            string TfsWIType = (string)methodInstance.GetMethod().GetDataClass().GetProperties()["TFSWorkItemType"]; //methodInstance.GetMethod().GetDataClass().Name
            string lobSystemName = lobSystemInstance.Name;

            //Log("ExecuteStatic", methodInstance.MethodInstanceType.ToString(), lobSystemName, TfsWIType);
            
            template = GenerateDynamicItemStructure(methodInstance);
            template = TFSHelper.FindWorkItem(TfsConnURL, ID, template, lobSystemName, TfsWIType);
            return template;
        }

        public static DynamicType[] ReadList(string filter)
        {
            DynamicType template;
            string TfsConnURL = (string)lobSystemInstance.GetProperties()["TFSConnectionURL"];
            string TfsWIType = (string)methodInstance.GetMethod().GetDataClass().GetProperties()["TFSWorkItemType"]; //methodInstance.GetMethod().GetDataClass().Name
            string lobSystemName = lobSystemInstance.Name;

            if(!filter.Contains("SELECT"))
                filter = (string)methodInstance.GetMethod().GetDataClass().GetProperties()["DefaultWorkItemQuery"];
                    
            //Log("ExecuteStatic", methodInstance.MethodInstanceType.ToString(), lobSystemName, TfsWIType);
            
            template = GenerateDynamicItemStructure(methodInstance);
            DynamicType[] dynItemsList = TFSHelper.QueryWorkItems(TfsConnURL, filter, template, lobSystemName, TfsWIType);
            return dynItemsList;
        }

        public static int Create(DynamicType newItem)
        {
            string TfsConnURL = (string)lobSystemInstance.GetProperties()["TFSConnectionURL"];
            string TfsProjName = (string)methodInstance.GetMethod().GetDataClass().GetProperties()["TFSProjectName"];
            string TfsWIType = (string)methodInstance.GetMethod().GetDataClass().GetProperties()["TFSWorkItemType"]; //methodInstance.GetMethod().GetDataClass().Name
            string lobSystemName = lobSystemInstance.Name;

            //Log("ExecuteStatic", methodInstance.MethodInstanceType.ToString(), lobSystemName, TfsWIType);

            int id = TFSHelper.CreateWorkItem(TfsConnURL, newItem, TfsWIType, TfsProjName, lobSystemName, TfsWIType);
            return id;
        }

        public static void Update(DynamicType updateNew)
        {
            string TfsConnURL = (string)lobSystemInstance.GetProperties()["TFSConnectionURL"];
            string TfsWIType = (string)methodInstance.GetMethod().GetDataClass().GetProperties()["TFSWorkItemType"]; //methodInstance.GetMethod().GetDataClass().Name
            string lobSystemName = lobSystemInstance.Name;

            //Log("ExecuteStatic", methodInstance.MethodInstanceType.ToString(), lobSystemName, TfsWIType);

            TFSHelper.UpdateWorkItem(TfsConnURL, updateNew, lobSystemName, TfsWIType);
        }

        public static void Delete(int ID)
        {
            string TfsConnURL = (string)lobSystemInstance.GetProperties()["TFSConnectionURL"];
            string TfsWIType = (string)methodInstance.GetMethod().GetDataClass().GetProperties()["TFSWorkItemType"]; //methodInstance.GetMethod().GetDataClass().Name
            string lobSystemName = lobSystemInstance.Name;

            //Log("ExecuteStatic", methodInstance.MethodInstanceType.ToString(), lobSystemName, TfsWIType);

            TFSHelper.DestroyWorkItem(TfsConnURL, ID, lobSystemName, TfsWIType);
        }
    }
}
